<?php
// +----------------------------------------------------------------------
// | YFCMF [ WE CAN DO IT MORE SIMPLE]
// +----------------------------------------------------------------------
// | Copyright (c) 2016-2020 http://yfcmf.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: rainfer <rainfer520@qq.com>
// +----------------------------------------------------------------------

namespace app\admin\model\blog;


class Blog extends \think\Model
{
    protected $autoWriteTimestamp = true;
    protected $createTime = 'addTime';
    protected $append = ['content', 'tags', 'cateName'];

    /**
     * 根据状态获取博客数
     *
     * @param $status
     *
     * @return int
     */
    public static function getCountByStatus($status = -1)
    {
        $where = [];
        if ($status != -1) {
            $where[] = ['status', '=', $status];
        }
        $where[] = ['isDel', '=', 0];
        $count = self::where($where)->count();
        return $count;
    }

    /**
     * 根据分类获取博客数(含下级分类)
     *
     * @param $cid
     *
     * @return int
     */
    public static function getCountByCids($cid)
    {
        $where = [];
        $where[] = ['isDel', '=', 0];
        // 获取该分类下所有cid
        $cids = BlogCategory::getChildrenIds($cid);
        $where[] = ['cid', 'in', $cids];
        $count = self::where($where)->count();
        return $count;
    }


    /**
     * 根据分类获取博客数(不含下级分类)
     *
     *
     * @return array
     * @throws
     */
    public static function getAllCategoriesCount()
    {
        $subsql = self::field('cid,count(cid) as sum')
            ->group('cid')
            ->buildSql();
        $list = BlogCategory::alias('a')
            ->field('a.id,a.title,a.pid,coalesce(b.sum,0) as sum')
            ->leftJoin([$subsql => 'b'], 'a.id=b.cid')
            ->select()
            ->toArray();
        return $list;
    }

    /**
     * 按分类博客数统计(不含下级分类)
     *
     * @param $cid
     *
     * @return int
     */
    public static function getCountByCid($cid)
    {
        $where = [];
        $where[] = ['isDel', '=', 0];
        $where[] = ['cid', '=', $cid];
        $count = self::where($where)->count();
        return $count;
    }

    /**
     * 获取文章列表
     *
     * @param $title
     * @param $cid
     * @param $tagId
     * @param $isDel
     * @param $createTime
     * @param $startTime
     * @param $endTime
     * @param $order
     * @param $page
     * @param $psize
     *
     * @return array
     * @throws
     */
    public static function getLists($title = '', $cid = -1, $tagId = -1, $isDel = -1, $createTime = 'all', $startTime = '', $endTime = '', $order = 'id desc', $page = 1, $psize = 10)
    {
        $where = [];
        if ($title) {
            $where[] = ['a.title|a.stitle', 'like', '%' . $title . '%'];
        }
        // 分类
        if ($cid !== -1) {
            $cids = BlogCategory::getChildrenIds($cid);
            if ($cids) {
                $where[] = ['a.cid', 'in', $cids];
            }
        }
        // 标签
        if ($tagId != -1) {
            // 有该标签的文章ids
            $ids = BlogTagAssoc::where('tagId', $tagId)->column('nid');
            if ($ids) {
                $where[] = ['a.id', 'in', $ids];
            } else {
                // 无文章,构建id=-1条件
                $where[] = ['a.id', '=', -1];
            }
        }
        if ($isDel !== -1) {
            $where[] = ['a.isDel', '=', $isDel];
        }
        // 创建时间
        $whereTime = [];
        if ($createTime == 'custom') {
            $whereTime[] = ['addTime', 'between', [$startTime, $endTime]];
        } else {
            $whereTime = where_between_time($createTime, 'addTime');
        }
        return self::alias('a')->where($where)->where($whereTime)
            ->field('a.*,b.title as cateName')
            ->join('blog_category b', 'a.cid=b.id')->order($order)->page($page, $psize)->select();
    }

    /**
     * 获取文章数量
     *
     * @param $title
     * @param $cid
     * @param $isDel
     * @param $tagId
     * @param $createTime
     * @param $startTime
     * @param $endTime
     *
     * @return int
     * @throws
     */
    public static function getTotal($title = '', $cid = -1, $tagId = -1, $isDel = -1, $createTime = 'all', $startTime = '', $endTime = '')
    {
        $where = [];
        if ($title) {
            $where[] = ['title|stitle', 'like', '%' . $title . '%'];
        }
        // 分类
        if ($cid !== -1) {
            $cids = BlogCategory::getChildrenIds($cid);
            if ($cids) {
                $where[] = ['cid', 'in', $cids];
            }
        }
        // 标签
        if ($tagId != -1) {
            // 有该标签的文章ids
            $ids = BlogTagAssoc::where('tagId', $tagId)->column('nid');
            if ($ids) {
                $where[] = ['id', 'in', $ids];
            } else {
                // 无文章,构建id=-1条件
                $where[] = ['id', '=', -1];
            }
        }
        if ($isDel !== -1) {
            $where[] = ['isDel', '=', $isDel];
        }
        // 创建时间
        $whereTime = [];
        if ($createTime == 'custom') {
            $whereTime[] = ['addTime', 'between', [$startTime, $endTime]];
        } else {
            $whereTime = where_between_time($createTime, 'addTime');
        }
        return self::where($where)->where($whereTime)->count();
    }

    /**
     * 删除文章(永久删除)
     *
     * @param $ids
     *
     * @return boolean
     * @throws
     */
    public static function del($ids)
    {
        $ids = is_array($ids) ? $ids : explode(',', $ids);
        self::StartTrans();
        try {
            // 删除主表
            self::destroy($ids);
            // 删除文章内容
            BlogContent::where('nid', 'in', $ids)->delete();
            // TODO 删除附件数据 删除评论
            self::commit();
        } catch (\think\Exception $e) {
            self::rollback();
            return false;
        }
        return true;
    }

    /**
     * 获取文章内容
     *
     * @param $value
     * @param $data
     *
     * @return int
     */
    public static function getContentAttr($value, $data)
    {
        return BlogContent::where(['nid' => $data['id']])->value('content');
    }

    /**
     * 获取文章标签
     *
     * @param $value
     * @param $data
     *
     * @return array
     * @throws
     */
    public static function getTagsAttr($value, $data)
    {
        return BlogTagAssoc::alias('a')->where(['a.nid' => $data['id']])
            ->join('blog_tag b', 'a.tagId=b.id')
            ->field('b.id,b.title')
            ->select()
            ->toArray();
    }

    /**
     * 获取文章标签
     *
     * @param $value
     * @param $data
     *
     * @return array
     * @throws
     */
    public static function getCateNameAttr($value, $data)
    {
        return BlogCategory::where('id', $data['cid'])->value('title');
    }

    /**
     * 更新文章标签
     *
     * @param $id
     * @param $tags
     *
     * @return boolean
     * @throws
     */
    public static function updateTags($id, $tags)
    {
        // 原有标签
        $blog = self::find($id);
        $tags_old = array_column($blog['tags'], 'id');;
        // 标签未改动,直接返回true
        if ($tags === $tags_old) {
            return true;
        }
        // 全部标签id数组
        $tagIds = BlogTag::getTagIds();
        // 旧/新差集(旧有 新无)
        $arr = array_diff($tags_old, $tags);
        // 新/旧差集(新有旧无)
        $arr_new = array_diff($tags, $tags_old);
        self::StartTrans();
        try {
            // 删除$arr
            if ($arr) {
                BlogTagAssoc::where([['nid', '=', $id], ['tagId', 'in', $arr]])->delete();
            }
            // 增加$arr_new
            $list = [];
            foreach ($arr_new as $value) {
                if (in_array($value, $tagIds)) {
                    $list[] = [
                        'nid' => $id,
                        'tagId' => $value
                    ];
                } else {
                    // 先插入tag表
                    $data = [
                        'title' => $value,
                        'addTime' => time()
                    ];
                    $tag = BlogTag::create($data);
                    if ($tag) {
                        $list[] = [
                            'nid' => $id,
                            'tagId' => $tag->id
                        ];
                    }
                }
            }
            // 批量添加
            $model = new BlogTagAssoc();
            $model->saveAll($list);
            self::commit();
        } catch (\think\Exception $e) {
            self::rollback();
            return false;
        }
        return true;
    }
}
